package cate.common.table;

import easy.java.dev.note.NoteField;
import easy.java.practice.errorcode.EcException;
import easy.java.time.DateTool;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.xssf.usermodel.XSSFRow;

import java.math.BigDecimal;
import java.util.*;

@Slf4j
public class XSSFRawRowWrap extends XSSFRowWrap {
    @Setter
    @NoteField("Sheet名称")
    private String sheetName = "unknown";
    @NoteField("字段名 -> 值")
    public Map<String, String> fieldToValue;

    public XSSFRawRowWrap(Map<String, String> fieldToValue) {
        super(null, new HashMap<>());
        this.fieldToValue = Optional.of(fieldToValue).orElse(new HashMap<>());
    }

    public XSSFRawRowWrap(XSSFRow row, Map<String, Integer> fieldIndexMap) {
        super(row, fieldIndexMap);
        throw new EcException("不支持该用法!");
    }

    /**
     * 是否所有值均为空
     */
    public boolean isAllValueEmpty() {
        return fieldToValue.values().stream().noneMatch(StringUtils::isNotEmpty);
    }

    @Override
    public String getString(String field, String defaultValue) {
        return fieldToValue.get(field);
    }

    @Override
    public String getString(String field) {
        return getString(field, null);
    }

    @Override
    public Integer getInteger(String field, Integer defaultValue) {
        String v = fieldToValue.get(field);
        if (StringUtils.isBlank(v)) {
            return defaultValue;
        }
        try {
            return new BigDecimal(v).intValue();
        } catch (Exception e) {
            report(this, field, e);
            return defaultValue;
        }
    }

    @Override
    public Integer getInteger(String field) {
        return getInteger(field, null);
    }

    @Override
    public Long getLong(String field, Long defaultValue) {
        String v = fieldToValue.get(field);
        if (StringUtils.isBlank(v)) {
            return defaultValue;
        }
        try {
            return new BigDecimal(v).longValue();
        } catch (Exception e) {
            report(this, field, e);
            return defaultValue;
        }
    }

    @Override
    public Long getLong(String field) {
        return getLong(field, null);
    }

    @Override
    public Short getShort(String field, Short defaultValue) {
        String v = fieldToValue.get(field);
        if (StringUtils.isBlank(v)) {
            return defaultValue;
        }
        try {
            return new BigDecimal(v).shortValue();
        } catch (Exception e) {
            report(this, field, e);
            return defaultValue;
        }
    }

    @Override
    public Short getShort(String field) {
        return getShort(field, null);
    }

    @Override
    public Byte getByte(String field, Byte defaultValue) {
        String v = fieldToValue.get(field);
        if (StringUtils.isBlank(v)) {
            return defaultValue;
        }
        try {
            return new BigDecimal(v).byteValue();
        } catch (Exception e) {
            report(this, field, e);
            return defaultValue;
        }
    }

    @Override
    public Byte getByte(String field) {
        return getByte(field, null);
    }

    @Override
    public Boolean getBoolean(String field, Boolean defaultValue) {
        String v = fieldToValue.get(field);
        if (StringUtils.isBlank(v)) {
            return defaultValue;
        }
        if ("true".equals(v)) {
            return true;
        }
        return v.contains("1");
    }

    @Override
    public Boolean getBoolean(String field) {
        return getBoolean(field, null);
    }

    @Override
    public Float getFloat(String field, Float defaultValue) {
        String v = fieldToValue.get(field);
        if (StringUtils.isBlank(v)) {
            return defaultValue;
        }
        try {
            return new BigDecimal(v).floatValue();
        } catch (Exception e) {
            report(this, field, e);
            return defaultValue;
        }
    }

    @Override
    public Float getFloat(String field) {
        return getFloat(field, null);
    }

    @Override
    public Double getDouble(String field, Double defaultValue) {
        String v = fieldToValue.get(field);
        if (StringUtils.isBlank(v)) {
            return defaultValue;
        }
        try {
            return new BigDecimal(v).doubleValue();
        } catch (Exception e) {
            report(this, field, e);
            return defaultValue;
        }
    }

    @Override
    public Double getDouble(String field) {
        return getDouble(field, null);
    }

    @Override
    public Date getDate(String field, Date defaultValue) {
        String v = fieldToValue.get(field);
        if (v == null) {
            return defaultValue;
        }
        try {
            return DateTool.instance().parseOrNull(v);
        } catch (Exception e) {
            report(this, field, e);
            return defaultValue;
        }
    }

    @Override
    public Date getDate(String field) {
        return getDate(field, null);
    }

    @Override
    public void setValue(String field, Object value) {
        throw new EcException("不支持该用法!");
    }

    private static void report(XSSFRawRowWrap xrw, String field, Exception e) {
        StringBuilder sb = new StringBuilder();
        for(String key : xrw.fieldToValue.keySet()) {
            String v = xrw.fieldToValue.get(key);
            try {
                sb.append(" ");
                sb.append(key);
                sb.append(":");
                sb.append(v);
            } catch (Exception ignored) {

            }
        }
        log.error("{} 配置表中 字段:{} 解析出现异常 {}  已被解析的数据：{} ", xrw.sheetName, field, e.getMessage(), sb);
    }
}
